home *** CD-ROM | disk | FTP | other *** search
/ ADA Programming Guide / ADA Programming Guide.iso / ada_gnu / adainc / s-expgen.adb < prev    next >
Text File  |  1996-01-30  |  5KB  |  135 lines

  1. ------------------------------------------------------------------------------
  2. --                                                                          --
  3. --                         GNAT RUNTIME COMPONENTS                          --
  4. --                                                                          --
  5. --                       S Y S T E M . E X P _ G E N                        --
  6. --                                                                          --
  7. --                                 B o d y                                  --
  8. --                                                                          --
  9. --                            $Revision: 1.7 $                              --
  10. --                                                                          --
  11. --           Copyright (c) 1992,1993,1994 NYU, All Rights Reserved          --
  12. --                                                                          --
  13. -- The GNAT library is free software; you can redistribute it and/or modify --
  14. -- it under terms of the GNU Library General Public License as published by --
  15. -- the Free Software  Foundation; either version 2, or (at your option) any --
  16. -- later version.  The GNAT library is distributed in the hope that it will --
  17. -- be useful, but WITHOUT ANY WARRANTY;  without even  the implied warranty --
  18. -- of MERCHANTABILITY  or  FITNESS FOR  A PARTICULAR PURPOSE.  See the  GNU --
  19. -- Library  General  Public  License for  more  details.  You  should  have --
  20. -- received  a copy of the GNU  Library  General Public License  along with --
  21. -- the GNAT library;  see the file  COPYING.LIB.  If not, write to the Free --
  22. -- Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.        --
  23. --                                                                          --
  24. ------------------------------------------------------------------------------
  25.  
  26. package body System.Exp_Gen is
  27.  
  28.    --------------------
  29.    -- Exp_Float_Type --
  30.    --------------------
  31.  
  32.    function Exp_Float_Type
  33.      (Left : Type_Of_Base; Right : Integer) return Type_Of_Base
  34.    is
  35.       pragma Unsuppress (Overflow_Check);
  36.       pragma Unsuppress (Division_Check);
  37.       pragma Unsuppress (Range_Check);
  38.  
  39.       Result : Type_Of_Base := 1.0;
  40.       Factor : Type_Of_Base := Left;
  41.       Exp    : Natural := Right;
  42.  
  43.    begin
  44.       --  We use the standard logarithmic approach, Exp gets shifted right
  45.       --  testing successive low order bits and Factor is the value of the
  46.       --  base raised to the next power of 2. For positive exponents we
  47.       --  multiply the result by this factor, for negative exponents, we
  48.       --  divide by this factor.
  49.  
  50.       if Exp >= 0 then
  51.  
  52.          --  For a positive exponent, if we get a constraint error during
  53.          --  this loop, it is an overflow, and the constraint error will
  54.          --  simply be passed on to the caller.
  55.  
  56.          while Exp /= 0 loop
  57.             if Exp rem 2 /= 0 then
  58.                Result := Result * Factor;
  59.             end if;
  60.  
  61.             Factor := Factor * Factor;
  62.             Exp := Exp / 2;
  63.          end loop;
  64.  
  65.          return Result;
  66.  
  67.       else -- Exp < 0 then
  68.  
  69.          --  For the negative exponent case, a constraint error during this
  70.          --  calculation happens if Factor gets too large, and the proper
  71.          --  response is to return 0.0, since what we essenmtially have is
  72.          --  1.0 / infinity, and the closest model number will be zero.
  73.  
  74.          begin
  75.  
  76.             while Exp /= 0 loop
  77.                if Exp rem 2 /= 0 then
  78.                   Result := Result * Factor;
  79.                end if;
  80.  
  81.                Factor := Factor * Factor;
  82.                Exp := Exp / 2;
  83.             end loop;
  84.  
  85.             return 1.0 / Result;
  86.  
  87.          exception
  88.  
  89.             when Constraint_Error =>
  90.                return 0.0;
  91.          end;
  92.       end if;
  93.    end Exp_Float_Type;
  94.  
  95.    ----------------------
  96.    -- Exp_Integer_Type --
  97.    ----------------------
  98.  
  99.    --  Note that negative exponents get a constraint error because the
  100.    --  subtype of the Right argument (the exponent) is Natural.
  101.  
  102.    function Exp_Integer_Type
  103.      (Left : Type_Of_Base; Right : Natural) return Type_Of_Base
  104.    is
  105.       pragma Unsuppress (Overflow_Check);
  106.       pragma Unsuppress (Division_Check);
  107.       pragma Unsuppress (Range_Check);
  108.  
  109.       Result : Type_Of_Base := 1;
  110.       Factor : Type_Of_Base := Left;
  111.       Exp    : Natural := Right;
  112.  
  113.    begin
  114.       --  We use the standard logarithmic approach, Exp gets shifted right
  115.       --  testing successive low order bits and Factor is the value of the
  116.       --  base raised to the next power of 2.
  117.  
  118.       --  Note: it is not worth special casing the cases of base values -1,0,+1
  119.       --  since the expander does this when the base is a literal, and other
  120.       --  cases will be extremely rare.
  121.  
  122.       while Exp /= 0 loop
  123.          if Exp rem 2 /= 0 then
  124.             Result := Result * Factor;
  125.          end if;
  126.  
  127.          Factor := Factor * Factor;
  128.          Exp := Exp / 2;
  129.       end loop;
  130.  
  131.       return Result;
  132.    end Exp_Integer_Type;
  133.  
  134. end System.Exp_Gen;
  135.